#include "server.h"

net_tcp::server::server(asio::io_service& iosev, unsigned int port):
	m_iosev(iosev),
	m_acceptor(asio::ip::tcp::acceptor(iosev, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)))
{
}

void net_tcp::server::accept()
{
	m_runing = true;
	m_iosev.post([this]()->void {
		accept_loop();
	});
}

void net_tcp::server::stop()
{
	m_runing = false;
	for (auto iter = m_sessionMap.begin();iter != m_sessionMap.end();++iter)
	{
		iter->second->close();
	}
	m_sessionMap.clear();
}

net_tcp::shared_session * net_tcp::server::find_session(int sessionId)
{
	auto iter = m_sessionMap.find(sessionId);
	if (iter != m_sessionMap.end()){
		return &iter->second;
	}
	return nullptr;
}

bool net_tcp::server::remove_session(int sessionId)
{
	shared_session* sess = find_session(sessionId);
	if (sess != nullptr)
	{
		(*sess)->close();
		m_sessionMap.erase(sessionId);
		return true;
	}
	return false;
}

void net_tcp::server::accept_loop()
{
	if (!m_runing)
		return;

	shared_session pSession = create_session();
	m_acceptor.async_accept(pSession->get_socket(), [this, pSession](asio::error_code error) -> void {
		if (!error) {
			on_connect(pSession);
			pSession->read_loop();
			accept_loop();
		}
		else {
			pSession->set_last_error(error);
			on_error(pSession);
		}
	});
}


net_tcp::shared_session net_tcp::server::create_session()
{
	std::shared_ptr<session> session(new session(m_iosev));
	session->regist_on_close(std::bind(&server::on_close, this, std::placeholders::_1));
	session->regist_on_recv(std::bind(&server::on_recv, this, std::placeholders::_1));
	session->regist_on_error(std::bind(&server::on_error, this, std::placeholders::_1));
	return session;
}

void net_tcp::server::on_connect(shared_session pSession)
{
	m_sessionMap[pSession->ID()] = pSession;
	on_connected(pSession);
}

void net_tcp::server::on_close(shared_session pSession)
{
	m_sessionMap.erase(pSession->ID());
	on_closeed(pSession);
}
